﻿//Date:2020-6-30
//Author:Xiaobin Wang

using System;
using System.Diagnostics;
using System.Windows.Forms;
using WangCon.About;
using System.Drawing;
using WangCon.Op;
using WangCon.XmlPar;
using WangCon.Lmi;
using System.Collections.Generic;

namespace WangCon
{

    public partial class FormMain : Form
    {

        #region Init Uninit

        public FormMain()
        {
            InitializeComponent();

            Init_Ui();

            Init_Param();

            System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;

        }

        private void Init_Ui()
        {

            this.tabPage_Test.Hide();
            this.tabPage_Height.Hide();

            imgCtrl.SetWin(new Point(5, 40), imgCtrl.Width - 10, imgCtrl.Height - 45);

            return;

        }

        #endregion Init Uninit

        #region Field

        const int REGION_MAX = 3200 * 10000;
        static int[] m_region = new int[REGION_MAX];
        byte[] imgReg = new byte[3200 * 15000];

        #endregion Field

        #region Flow

        public int Flow_T_1()
        {
            try
            {
                //????优化
                heightCtrl1.m_HeightData.data = imgCtrl.m_data.data;
                heightCtrl1.m_HeightData.width = imgCtrl.m_data.width;
                heightCtrl1.m_HeightData.height = imgCtrl.m_data.height;
                heightCtrl1.m_HeightData.xInterval = imgCtrl.m_data.xInterval;
                heightCtrl1.m_HeightData.yInterval = imgCtrl.m_data.yInterval;
                heightCtrl1.m_HeightData.zInterval = imgCtrl.m_data.zInterval;

                PtAng ptAng_model = new PtAng();
                PtAng ptAng_run = new PtAng();
                Line line_1;
                Line line_2;

                matchCtrl1.GetModel(out ptAng_model);

                matchCtrl1.Run(ref imgCtrl.m_data, out ptAng_run, out line_1, out line_2);

                //matchCtrl1.ShowRun();
                heightCtrl1.Run(ptAng_run, ptAng_model, out heightCtrl1.arr_dist);

                int count_Calc = heightCtrl1.m_now_calc.Count;
                int count_Plane = heightCtrl1.m_now_plane.Count;

                imgCtrl.ClearCont();
                imgCtrl.ClearMess();

                for (int i = 0; i < count_Calc; i++)
                {
                    imgCtrl.AddCont(DrawStruct.Circle,
                        new double[5]{ heightCtrl1.m_now_calc[i].x1,
                        heightCtrl1.m_now_calc[i].y1
                        ,23,0,0.0}, 3, Color.HotPink, 1);
                    //imgCtrl.DispCircle(sPtCalc[i], 23, Color.HotPink, 5, 1);
                }

                for (int i = 0; i < count_Plane; i++)
                {
                    imgCtrl.AddCont(DrawStruct.Cross,
                        new double[5] { heightCtrl1.m_now_plane[i].x1,
                        heightCtrl1.m_now_plane[i].y1,
                    0.78,13,0.0}, 3, Color.DarkGreen, 1);
                }

                for (int i = 0; i < count_Calc; i++)
                {
                    imgCtrl.AddMess("Height " + (i + 1).ToString()
                        + " : " + heightCtrl1.arr_dist[i].ToString("f4") + "mm",
                        15, Brushes.Green, 20, 20 + i * 20, false, 0);
                }

                imgCtrl.ShowMess();
                imgCtrl.ShowCont();

            }
            catch (Exception ex)
            {
                Info("Flow_T_1 Err:" + ex.Message);
                Info("Flow_T_1 Err:" + ex.StackTrace);
                Info("Flow_T_1 Err:" + ex.Source);
                return -1;
            }

            return 0;

        }

        private delegate int DelintFunc();

        #endregion Flow

        #region Log Trace Info

        WangCon.Main.Log.LogClass mLog = new WangCon.Main.Log.LogClass("Main");

        public int LogTraceInfo(string str)
        {
            mLog.Write(str);
            Trace.WriteLine(str);
            InfoText.AppendText("\r\n" + str);

            return 0;
        }

        public int LogTrace(string str)
        {
            mLog.Write(str);
            Trace.WriteLine(str);

            return 0;
        }

        public int Info(string str)
        {
            InfoText.AppendText("\r\n" + str);
            return 0;
        }

        #endregion Log Trace Info

        #region Param

        private XmlParClass m_Xml = new XmlParClass();

        private int Init_Param()
        {
            Read_Param_Sys();

            return 0;
        }

        private int Read_Param_Sys()
        {
            //mXml.ReadNode("//PtPro/Pt" + index.ToString() + "/X", out ProPt.X);
            return 0;

        }

        #endregion Param

        #region Unit Test

        private void btn_Test_Click(object sender, EventArgs e)
        {
            //Unit_Test_mea_line();
            //Unit_Test_FitPlance();
            //Unit_Test_XmlPar();
            //Unit_Test_r();
            Unit_Test_LmiCtrl();

            return;
        }

        private void Unit_Test_LmiCtrl()
        {
            List<string> list = new List<string>();
            list.Add("192.168.0.10");
            ListLmiCam lmiCam = new ListLmiCam();
            lmiCam.Init(list);

            return;

        }

        private void Unit_Test_Atan2()
        {

            double[] angle = new double[10] { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
            angle[0] = Math.Atan2(0, 0) * 180.0 / Math.PI;
            angle[1] = Math.Atan2(10, 0) * 180.0 / Math.PI;
            angle[2] = Math.Atan2(40, 10) * 180.0 / Math.PI;
            angle[3] = Math.Atan2(30, 10) * 180.0 / Math.PI;
            angle[4] = Math.Atan2(20, 10) * 180.0 / Math.PI;
            angle[5] = Math.Atan2(10, 10) * 180.0 / Math.PI;

            foreach (double a in angle)
            {
                Trace.WriteLine(a);
            }

        }

        private void Unit_Test_XmlPar()
        {

            XmlPar.XmlParClass xml_par = new XmlPar.XmlParClass();

            string file = @"MatchCtrl.xml";
            xml_par.Load(@"./CtrlPar/", file);

            //int err = xml_par.IsExist("//roi_plane/sss");
            int err = xml_par.Write("MatchCtrl/match1/Mea66/P1", 12);
            //int err1 = xml_par.Create("//SS1");
            //int err2 = xml_par.Create("//roi_plane/s1/x/x1");
            //xml_par.
            Trace.WriteLine(err);

        }

        private void Unit_Test_Log()
        {
            SimpleLog.SimpleLogClass simLog = new SimpleLog.SimpleLogClass();
            simLog.WriteLog("sdfsdxxv");

            return;
        }

        private void Unit_Test_mea_line()
        {
            int thres = 90000;
            int sigma = 1;
            int trans = 0;
            int select = 0;
            int small_len2 = 9;
            int numMes = 10;

            RoiRect2 rect2 = new RoiRect2();
            rect2.x = 1108.0;
            rect2.y = 845.0;
            rect2.len1 = 200.0;
            rect2.len2 = 50.0;
            rect2.angle = Math.PI * (-0.5);
            Line line = new Line();

            int errM = mea_line(imgCtrl.m_data.data,
                imgCtrl.m_data.width, imgCtrl.m_data.height,
                rect2, numMes, small_len2,
                  thres, sigma, trans, select, ref line);

            imgCtrl.DispLine(new Point((int)line.beg.X, (int)line.beg.Y),
                                 new Point((int)line.end.X, (int)line.end.Y), Color.Green, 3, 1);

            return;

        }

        private void Unit_Test_r()
        {
            Int32[] data = new Int32[4];
            int err = Test(data, 2000);

            string strHex = "";

            for (int i = 0; i < 4; i++)
            {
                strHex += String.Format("{0:X}", data[i]);
            }

            Trace.WriteLine("Unit_Test_r:" + strHex);

            return;

        }

        #region Cpp2CSharp

        //用于C# 调用 C++ dll 相关接口
        private void Unit_Test_Cpp2CSharp()
        {

            return;
        }

        #endregion Cpp2CSharp

        #endregion Unit Test

        #region Data

        DataSave mData = new DataSave();

        #endregion Data

        #region Op

        private int Region2ImgReg(Int32[] reg, ref byte[] imgReg, int width, int height)
        {

            //if (imgReg.w != w || imgReg.h != h)
            //{
            //    return -2;
            //}
            int iType = reg[0];
            int count = reg[1];
            //Trace.WriteLine("count:--" + count.ToString());

            for (int i = 0; i < height; i++)
            {
                for (int j = 0; j < width; j++)
                {
                    imgReg[i * width + j] = 0;
                }
            }

            for (int i = 0; i < count; i++)
            {
                int num_y = reg[i * 3 + 2];
                int num_x0 = reg[i * 3 + 3];
                int num_x1 = reg[i * 3 + 4];

                if (num_y < 0 || num_y >= height ||
                    num_x0 < 0 || num_x0 >= width ||
                    num_x1 < 0 || num_x1 >= width)
                {
                    return -2;
                }

                for (int index = num_x0; index <= num_x1; index++)
                {
                    imgReg[num_y * width + index] = 255;
                }

            }

            return 0;

        }

        public struct Point3d
        {
            public double x;
            public double y;
            public double z;

        }

        #endregion Op

        #region Ui

        private void btn_Run_Click(object sender, EventArgs e)
        {
            DelintFunc fun = new DelintFunc(Flow_T_1);
            fun.BeginInvoke(null, null);
        }

        private void 关于ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            FormAbout fm = new FormAbout();

            fm.ShowDialog();

        }

        Point mouseOff;//鼠标移动位置变量
        bool leftFlag;//标签是否为左键

        private void Form1_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                mouseOff = new Point(-e.X, -e.Y); //得到变量的值
                leftFlag = true;                  //点击左键按下时标注为true;
            }
        }

        private void Form1_MouseMove(object sender, MouseEventArgs e)
        {
            if (leftFlag)
            {
                Point mouseSet = Control.MousePosition;
                mouseSet.Offset(mouseOff.X, mouseOff.Y);  //设置移动后的位置
                Location = mouseSet;
            }
        }

        private void Form1_MouseUp(object sender, MouseEventArgs e)
        {
            if (leftFlag)
            {
                leftFlag = false;//释放鼠标后标注为false;
            }
        }

        private void 退出ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Close();
        }


        #endregion Ui

        #region Height Func

        private void btn_Height_HeightVal_Click(object sender, EventArgs e)
        {
            try
            {
                heightCtrl1.m_HeightData.data = imgCtrl.m_data.data;
                heightCtrl1.m_HeightData.width = imgCtrl.m_data.width;
                heightCtrl1.m_HeightData.height = imgCtrl.m_data.height;
                heightCtrl1.m_HeightData.xInterval = imgCtrl.m_data.xInterval;
                heightCtrl1.m_HeightData.yInterval = imgCtrl.m_data.yInterval;
                heightCtrl1.m_HeightData.zInterval = imgCtrl.m_data.zInterval;

                //????
                PtAng ptAng_now = new PtAng();
                PtAng ptAng_model = new PtAng();
                //heightCtrl1.Run(ptAng_now, ptAng_model, out heightCtrl1.arr_dist);

                int count_Calc = heightCtrl1.m_list_roi_calc.Count;
                int count_Plane = heightCtrl1.m_list_roi_plane.Count;

                imgCtrl.ClearCont();
                imgCtrl.ClearMess();

                for (int i = 0; i < count_Calc; i++)
                {
                    imgCtrl.AddCont(DrawStruct.Circle,
                        new double[4]{ heightCtrl1.m_list_roi_calc[i].x1,
                        heightCtrl1.m_list_roi_calc[i].y1
                        ,23,0}, 3, Color.HotPink, 1);
                    //imgCtrl.DispCircle(sPtCalc[i], 23, Color.HotPink, 5, 1);
                }

                for (int i = 0; i < count_Plane; i++)
                {

                    imgCtrl.AddCont(DrawStruct.Cross,
                        new double[4] { heightCtrl1.m_list_roi_plane[i].x1,
                        heightCtrl1.m_list_roi_plane[i].y1,
                    0.78,13}, 3, Color.DarkGreen, 1);

                }

                for (int i = 0; i < count_Calc; i++)
                {
                    imgCtrl.AddMess("Height " + (i + 1).ToString()
                        + " : " + heightCtrl1.arr_dist[i].ToString("f4") + "mm", 15, Brushes.Green, 20, 20 + i * 20, false, 0);
                }

                imgCtrl.ShowCont();
                imgCtrl.ShowMess();

            }
            catch (Exception ex)
            {
                Info("Flow_T_1 Err:" + ex.Message);
                return;
            }

            return;

        }

        private void btn_FitPlance_Click(object sender, EventArgs e)
        {

        }

        private void btn_GetPlanePt_Click(object sender, EventArgs e)
        {

            int count = imgCtrl.m_list_tmpPt.Count;

            if (count == 0)
            {
                return;
            }

            double x = imgCtrl.m_list_tmpPt[count - 1].x;
            double y = imgCtrl.m_list_tmpPt[count - 1].y;
            double z = imgCtrl.m_list_tmpPt[count - 1].z;
            int len1 = 5;
            int len2 = 5;
            heightCtrl1.PlanePt_Add((int)x, (int)y, len1, len2);
            imgCtrl.m_list_tmpPt.RemoveAt(count - 1);

        }

        private void btn_GetCalPt_Click(object sender, EventArgs e)
        {
            int count = imgCtrl.m_list_tmpPt.Count;

            if (count == 0)
            {
                return;
            }

            double x = imgCtrl.m_list_tmpPt[count - 1].x;
            double y = imgCtrl.m_list_tmpPt[count - 1].y;
            double z = imgCtrl.m_list_tmpPt[count - 1].z;
            int len1 = 5;
            int len2 = 5;
            heightCtrl1.CalcPt_Add((int)x, (int)y, len1, len2);
            imgCtrl.m_list_tmpPt.RemoveAt(count - 1);

        }

        #endregion Height Func

        #region Operator

        static IntPtr ArrayToIntptr(Int32[] source)
        {
            if (source == null)
            {
                return IntPtr.Zero;
            }

            unsafe
            {
                fixed (Int32* point = source)
                {
                    IntPtr ptr = new IntPtr(point);
                    return ptr;
                }
            }

        }

        static IntPtr ArrayToIntptr(byte[] source)
        {
            if (source == null)
            {
                return IntPtr.Zero;
            }

            unsafe
            {
                fixed (byte* point = source)
                {
                    IntPtr ptr = new IntPtr(point);
                    return ptr;
                }
            }

        }

        #endregion Operator


    }

}
